package com.ht.guice.fx.fxml;

import com.google.inject.Injector;
import com.ht.guice.fx.FXMLController;
import javafx.fxml.FXMLLoader;
import javafx.util.Callback;

import javax.inject.Inject;
import java.io.IOException;
import java.net.URL;

/**
 * Created with IntelliJ IDEA.
 *
 * @author: bcw 14-2-21 下午1:17
 * To change this template use File | Settings | File Templates.
 */
public class GuiceFXMLLoader {
    private final Injector injector;

    @Inject
    public GuiceFXMLLoader(Injector injector) {
        this.injector = injector;
    }

    public Result loadFXML(Class<?> controllerClass, String fxmlName) throws IOException {
        if (fxmlName == null) {
            return loadFXML(controllerClass);
        }

        URL url = controllerClass.getResource(fxmlName);

        final FXMLLoader loader = new FXMLLoader(url);
        loader.setControllerFactory(new Callback<Class<?>, Object>() {
            @Override
            public Object call(final Class<?> param) {
                return param == null ? null : injector.getInstance(param);
            }
        });

        return new Result(loader.load(), loader.getController());
    }

    public Result loadFXML(Class<?> controllerClass) throws IOException {
        FXMLController controllerAnnotation = (FXMLController) controllerClass
                .getAnnotation(FXMLController.class);
        String fxmlName = null;
        if (controllerAnnotation != null) {
            fxmlName = controllerAnnotation.value();
        } else {
            fxmlName = controllerClass.getSimpleName() + ".fxml";
        }
        return loadFXML(controllerClass, fxmlName);
    }

    public static class Result {
        private Object root;
        private Object controller;

        public Result(Object root, Object controller) {
            this.root = root;
            this.controller = controller;
        }

        public <N> N getRoot() {
            return (N) root;
        }

        public <C> C getController() {
            return (C) controller;
        }
    }
}
